package edu.mobbuzz.web.pages;

import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.commons.io.output.ByteArrayOutputStream;
import org.apache.tapestry5.ComponentResources;
import org.apache.tapestry5.Link;
import org.apache.tapestry5.StreamResponse;
import org.apache.tapestry5.annotations.Persist;
import org.apache.tapestry5.annotations.Property;
import org.apache.tapestry5.ioc.annotations.Inject;
import org.apache.tapestry5.ioc.services.TypeCoercer;
import org.apache.tapestry5.services.Response;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartUtilities;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.DateAxis;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYBarRenderer;
import org.jfree.chart.renderer.xy.XYItemRenderer;
import org.jfree.data.time.Day;
import org.jfree.data.time.Hour;
import org.jfree.data.time.Month;
import org.jfree.data.time.TimeSeries;
import org.jfree.data.time.TimeSeriesCollection;
import org.jfree.data.xy.IntervalXYDataset;

import edu.mobbuzz.web.base.SecureBasePage;
import edu.mobbuzz.web.facade.ManagementFacade;

public class MonitoringPage extends SecureBasePage{
	@Inject
    private ComponentResources _resources;
	@Inject
    private TypeCoercer _coercer;
	
	@Persist("flash")
	@Property
	private Date twawal, twakhir;
	private ManagementFacade managementFacade;
		
	public ManagementFacade getManagementFacade() {
		if(managementFacade==null){
			managementFacade = new ManagementFacade();
		}
		return managementFacade;
	}
	
	void onSuccessFromChartForm(){	
		List countDailyChart = getManagementFacade().getCountDailyChart(twawal, twakhir);
		for (Iterator iter = countDailyChart.iterator(); iter.hasNext();) {
 	    	Map element = (Map) iter.next();
 	    	System.out.println("111111" + Integer.parseInt(element.get("jumlah").toString()));
 	    	System.out.println("2222222" +element.get("waktu").toString());
		}
		/*if(twawal!=null && twakhir!=null){
			List countDailyChart = getManagementFacade().getCountDailyChart(twawal, twakhir);
			for (Iterator iter = countDailyChart.iterator(); iter.hasNext();) {
	 	    	Map element = (Map) iter.next();
	 	    	System.out.println(Integer.parseInt(element.get("jumlah").toString()));
	 	    	System.out.println(element.get("waktu").toString());
			}
			
			List countMonthlyChart = getManagementFacade().getCountMonthlyChart(twawal, twakhir);
			for (Iterator iter = countMonthlyChart.iterator(); iter.hasNext();) {
	 	    	Map element = (Map) iter.next();
	 	    	System.out.println(Integer.parseInt(element.get("jumlah").toString()));
	 	    	System.out.println(element.get("waktu").toString());
			}
			
			List countYearlyChart = getManagementFacade().getCountYearlyChart(twawal, twakhir);
			for (Iterator iter = countYearlyChart.iterator(); iter.hasNext();) {
	 	    	Map element = (Map) iter.next();
	 	    	System.out.println(Integer.parseInt(element.get("jumlah").toString()));
	 	    	System.out.println(element.get("waktu").toString());
			}
		}*/
	}
	
	public Link getDailyChart(){		
        return _resources.createEventLink("chart", new Object[]{"400","400", twawal.getTime(), twakhir.getTime()});
    }
	
	public StreamResponse onChart(final int width, final int height, final Long _twawal, final Long _twakhir){       
		
        return new StreamResponse(){
            public String getContentType(){
                return "image/gif";
            }
            public InputStream getStream() throws IOException {
                BufferedImage image  = generateDailyChart(_twawal, _twakhir).createBufferedImage(width, height);
                ByteArrayOutputStream byteArray = new ByteArrayOutputStream() ;
                ChartUtilities.writeBufferedImageAsPNG(byteArray, image) ;
                return new ByteArrayInputStream(byteArray.toByteArray());
            }
            public void prepareResponse(Response response){}
        };
    }

	public JFreeChart generateDailyChart(Long _twawal, Long _twakhir) {
		Date _twawaltemp = new Date();
		_twawaltemp.setTime(_twawal);		
		Date _twakhirtemp = new Date();
		_twakhirtemp.setTime(_twakhir);		
		
		Calendar twAwalTemp = Calendar.getInstance();
		Calendar twAkhirTemp = Calendar.getInstance();			
		
		twAwalTemp.setTime(_twawaltemp);
		twAkhirTemp.setTime(_twakhirtemp);
		
		twAwalTemp.set(Calendar.HOUR_OF_DAY, 0);
		twAkhirTemp.set(Calendar.HOUR_OF_DAY, 24);
				
		List countDailyChart = getManagementFacade().getCountDailyChart(_twawaltemp, _twakhirtemp);	
		
		String tw1 = new SimpleDateFormat("dd-MMMM-yyyy").format(twAwalTemp.getTime());
		String tw2 = new SimpleDateFormat("dd-MMMM-yyyy").format(twAkhirTemp.getTime());
		JFreeChart chart = ChartFactory.createXYBarChart(
				 "Jabber Server Daily Traffic ("+tw1+" to "+tw2+")", 
				 "Hour", 
				 true, 
				 "Traffic", 
				 createDailyDataset(countDailyChart), 
				 PlotOrientation.VERTICAL, 
				 true, 
				 false, 
				 false);
		XYPlot plot = (XYPlot) chart.getPlot();
		plot.setBackgroundPaint(Color.lightGray);
		plot.setDomainGridlinePaint(Color.RED); //grid for Y
		plot.setRangeGridlinePaint(Color.BLUE); // grid for X
		plot.setDomainCrosshairVisible(true);
		plot.setRangeCrosshairVisible(true);
		
		XYItemRenderer r = plot.getRenderer();
		if (r instanceof XYBarRenderer) {
			XYBarRenderer renderer = (XYBarRenderer) r;
			renderer.setBaseItemLabelsVisible(true);
			renderer.setBaseSeriesVisible(true);
		}

		DateAxis axis = (DateAxis) plot.getDomainAxis();
		axis.setDateFormatOverride(new SimpleDateFormat("HH"));
		NumberAxis numberaxis = (NumberAxis)plot.getRangeAxis();
        numberaxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());
        
        return chart;

    }	

	private static IntervalXYDataset createDailyDataset(List data){
		TimeSeries timeseries = new TimeSeries("Traffic", org.jfree.data.time.Hour.class);		
	    Day day = new Day();	    
	    int dailyChart[] = new int[24];    	   	
    	
 	    for (Iterator iter = data.iterator(); iter.hasNext();) {
 	    	Map element = (Map) iter.next(); 	    	
 	    	dailyChart[Integer.parseInt(element.get("waktu").toString())] = Integer.parseInt(element.get("jumlah").toString());
 	    }
	    
		for(int i=0;i<dailyChart.length;i++){			
			timeseries.add(new Hour(i, day),dailyChart[i]); 
		}
			
	    TimeSeriesCollection timeseriescollection = new TimeSeriesCollection();
        timeseriescollection.setDomainIsPointsInTime(true);
        timeseriescollection.addSeries(timeseries);
        			    
	    return timeseriescollection;
    }
	
	/* =============
	 * CHART BULANAN 
	 =============== */ 
	
	public Link getMonthlyChart(){		
        return _resources.createEventLink("monthlyChart", new Object[]{"400","400", twawal.getTime(), twakhir.getTime()});
    }
	
	public StreamResponse onMonthlyChart(final int width, final int height, final Long _twawal, final Long _twakhir){       
		
        return new StreamResponse(){
            public String getContentType(){
                return "image/gif";
            }
            public InputStream getStream() throws IOException {
                BufferedImage image  = generateMonthlyChart(_twawal, _twakhir).createBufferedImage(width, height);
                ByteArrayOutputStream byteArray = new ByteArrayOutputStream() ;
                ChartUtilities.writeBufferedImageAsPNG(byteArray, image) ;
                return new ByteArrayInputStream(byteArray.toByteArray());
            }
            public void prepareResponse(Response response){}
        };
    }
	
	public JFreeChart generateMonthlyChart(Long _twawal, Long _twakhir) {
		Date _twawaltemp = new Date();
		_twawaltemp.setTime(_twawal);
		Date _twakhirtemp = new Date();
		_twakhirtemp.setTime(_twakhir);
		
		Calendar twAwalTemp = new GregorianCalendar();
		Calendar twAkhirTemp = new GregorianCalendar();
		
		
		twAwalTemp.setTime(_twawaltemp);
		twAkhirTemp.setTime(_twawaltemp);
		
		twAwalTemp.set(Calendar.DAY_OF_MONTH, 1);
		int lastDay = twAwalTemp.getActualMaximum(Calendar.DAY_OF_MONTH)+1;
		twAkhirTemp.set(Calendar.DAY_OF_MONTH, lastDay);	
		
		List countMonthlyChart = getManagementFacade().getCountMonthlyChart(twAwalTemp.getTime(), twAkhirTemp.getTime());
		
		String tw1 = new SimpleDateFormat("MMMM-yyyy").format(twAwalTemp.getTime());
		String tw2 = new SimpleDateFormat("MM-yyyy").format(twAkhirTemp.getTime());
		
		JFreeChart chart = ChartFactory.createXYBarChart(
				 "Jabber Server Monthly Traffic ("+tw1+")", 
				 "Date", 
				 true, 
				 "Volume", 
				 createDatasetBulanan(countMonthlyChart, twAwalTemp), 
				 PlotOrientation.VERTICAL, 
				 true, 
				 false, 
				 false);
		 
		XYPlot plot = (XYPlot) chart.getPlot();
		plot.setBackgroundPaint(Color.lightGray);
		plot.setDomainGridlinePaint(Color.RED); //grid for Y
		plot.setRangeGridlinePaint(Color.BLUE); // grid for X
		plot.setDomainCrosshairVisible(true);
		plot.setRangeCrosshairVisible(true);
		
		XYItemRenderer r = plot.getRenderer();
		if (r instanceof XYBarRenderer) {
			XYBarRenderer renderer = (XYBarRenderer) r;
			renderer.setBaseItemLabelsVisible(true);
			renderer.setBaseSeriesVisible(true);
		}

		DateAxis axis = (DateAxis) plot.getDomainAxis();
		axis.setDateFormatOverride(new SimpleDateFormat("dd"));
		NumberAxis numberaxis = (NumberAxis)plot.getRangeAxis(); // y bilangan bulat
        numberaxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());

        return chart;
	}
	
    private static IntervalXYDataset createDatasetBulanan(List send, Calendar twAwal)
    {
    	TimeSeries timeseries = new TimeSeries("Traffic",org.jfree.data.time.Day.class); 
    	
    	int monthlyChart[] = new int[twAwal.getActualMaximum(Calendar.DAY_OF_MONTH)+1]; 	
    		    
    	for (Iterator iter = send.iterator(); iter.hasNext();) {
 	    	Map element = (Map) iter.next();
 	    	monthlyChart[Integer.parseInt(element.get("waktu").toString())] = Integer.parseInt(element.get("jumlah").toString());    
 		}
	    
	    for(int i=1;i<monthlyChart.length;i++){			
			try{							
				timeseries.add(new Day(i, twAwal.get(Calendar.MONTH)+1,  twAwal.get(Calendar.YEAR)), monthlyChart[i]);
		       
		    }catch(Exception exception){
		    	
		    	System.err.println(exception.getMessage());
		    }
		}
       
        TimeSeriesCollection timeseriescollection = new TimeSeriesCollection();
        timeseriescollection.setDomainIsPointsInTime(true);
        timeseriescollection.addSeries(timeseries);
        return timeseriescollection;
   }
   
    /* =============
	 * CHART TAHUNAN 
	 =============== */
    
    public Link getYearlyChart(){		
        return _resources.createEventLink("yearlyChart", new Object[]{"400","400", twawal.getTime(), twakhir.getTime()});
    }
	
	public StreamResponse onYearlyChart(final int width, final int height, final Long _twawal, final Long _twakhir){       
		
        return new StreamResponse(){
            public String getContentType(){
                return "image/gif";
            }
            public InputStream getStream() throws IOException {
                BufferedImage image  = generateYearlyChart(_twawal, _twakhir).createBufferedImage(width, height);
                ByteArrayOutputStream byteArray = new ByteArrayOutputStream() ;
                ChartUtilities.writeBufferedImageAsPNG(byteArray, image) ;
                return new ByteArrayInputStream(byteArray.toByteArray());
            }
            public void prepareResponse(Response response){}
        };
    }
    public JFreeChart generateYearlyChart(Long _twawal, Long _twakhir) {
    	Date _twawaltemp = new Date();
		_twawaltemp.setTime(_twawal);
		Date _twakhirtemp = new Date();
		_twakhirtemp.setTime(_twakhir);
		
    	Calendar twAwalTemp = Calendar.getInstance();
		Calendar twAkhirTemp = Calendar.getInstance();
				
		twAwalTemp.setTime(_twawaltemp);
		twAkhirTemp.setTime(_twawaltemp);
		
		twAwalTemp.set(twAwalTemp.get(Calendar.YEAR),Calendar.JANUARY,01);
		twAkhirTemp.set(twAwalTemp.get(Calendar.YEAR),Calendar.DECEMBER,31);
		
		List countYearlyChart = getManagementFacade().getCountYearlyChart(twAwalTemp.getTime(), twAkhirTemp.getTime());
		
		String tw1 = new SimpleDateFormat("yyyy").format(twAwalTemp.getTime());
		
		JFreeChart chart = ChartFactory.createXYBarChart(
				 "Jabber Server Yearly Traffic ("+tw1+")", 
				 "Traffic", 
				 true, 
				 "Volume", 
				 createYearlyDataset(countYearlyChart, twAwalTemp), 
				 PlotOrientation.VERTICAL, 
				 true, 
				 false, 
				 false);
		 
		XYPlot plot = (XYPlot) chart.getPlot();
		plot.setBackgroundPaint(Color.lightGray);
		plot.setDomainGridlinePaint(Color.RED); //grid for Y
		plot.setRangeGridlinePaint(Color.BLUE); // grid for X
		plot.setDomainCrosshairVisible(true);
		plot.setRangeCrosshairVisible(true);
		
		XYItemRenderer r = plot.getRenderer();
		if (r instanceof XYBarRenderer) {
			XYBarRenderer renderer = (XYBarRenderer) r;
			renderer.setBaseItemLabelsVisible(true);
			renderer.setBaseSeriesVisible(true);
		}

		DateAxis axis = (DateAxis) plot.getDomainAxis();
		axis.setDateFormatOverride(new SimpleDateFormat("MMM"));
		NumberAxis numberaxis = (NumberAxis)plot.getRangeAxis(); // y bilangan bulat
        numberaxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());

		return chart;
	

	}
	
    private static IntervalXYDataset createYearlyDataset(List send, Calendar twAwal)
    {
    	TimeSeries timeseries = new TimeSeries("Traffic", org.jfree.data.time.Month.class);
    	
    	int yearlyChart[] = new int[13];  	
    	
 	    
    	for (Iterator iter = send.iterator(); iter.hasNext();) {
 	    	Map element = (Map) iter.next(); 	    	
 	    	yearlyChart[Integer.parseInt(element.get("waktu").toString())] = Integer.parseInt(element.get("jumlah").toString());
 	    	    
 		}
	    
    	for(int i=1;i<yearlyChart.length;i++){			
			try{				
				timeseries.add(new Month(i, twAwal.get(Calendar.YEAR)), new Double(yearlyChart[i]));
				
		    }catch(Exception exception){
		    	
		        System.err.println(exception.getMessage());
		    }
		}
           
        TimeSeriesCollection timeseriescollection = new TimeSeriesCollection();
        timeseriescollection.addSeries(timeseries);
        return timeseriescollection;
    }

}
